Canigó - Servei de FTP
SERVEI DE FTP
IntroduccióPropòsitEl servei de FTP de canigo permet enviar i rebre: arxius, directoris sencers o Streams, entre el servidor on s'executa l'aplicació a altres servidors. El servei està basat en Jakarta Commons Net, es tracta d'un projecte open source englobat dins del projecte Jakarta que proporciona les funcionalitats clàssiques associades al protocol FTP, però com a característica destacada la possibilitat de transferir els fitxers o els streams en paral- lel. Context i Escenaris d'ÚsEl servei de FTP es troba dins dels serveis d'integració de canigo. El seu ús és necessari en cas de voler intercanviar fitxers entre servidors utilitzant el protocol FTP. Versions i DependènciesLes dependències descrites a la següent url son requerides per tal de compilar i fer funcionar el projecte: A qui va dirigitAquest document va dirigit als següents perfils:
Documents i Fonts de Referència
GlossariFTP Stream Download Upload Socket Descripció DetalladaArquitectura i Componentscanigo ofereix una arquitectura d'ús del protocol FTP totalment deslligada de qualsevol implementació. Els components podem classificar-los en:
JavaDoc: http://canigo.ctti.gencat.net/confluence/canigodocs/site/canigo2_0/canigo-services-ftp/apidocs/index.html Instal- lació i ConfiguracióInstal- lacióLa instal- lació del servei requereix de la utilització de la llibreria 'canigo-services-ftp' i les dependències indicades a l'apartat 'Introducció - Versions i Dependències'. Per la instal- lació del component Jakarta Commons Net, no es requereix res a part del JAR indicat en la dependència "Jakarta Commons Net". ConfiguracióLa configuració del Servei de FTP implica:
Definició del Servei
La definició del servei requereix configurar un bean amb un identificador (es recomana usar 'ftpService' ) i els següents atributs: Atributs:
També es poden configurar les següents propietats:
Exemple:
... <!- FTP service -> <bean id="ftpService" class="net.gencat.ctti.canigo.services.ftp.impl.FtpClient"> <property name="logService"> <ref local="loggingService"/> </property> </bean> ... <bean id="loggingService" class="net.gencat.ctti.canigo.services.logging.log4j. Log4JServiceImpl" init-method="init"> ... </bean> ... Utilització del ServeiRealitzar connexióTal i com s'ha comentat a l'apartat 'Arquitectura i Components' les classes principals per realitzar transferències de fitxers/streams es troben al package 'net.gencat.ctti.canigo.services.ftp'. Per realitzar una connexió seguirem un patró com el mostrat en el següent exemple:
if (this.ftpClient != null ) { ftpClient.login(userName, password, host); } Realitzarem doncs els següents passos:
Es crida el mètode login() que amb els següents paràmetres:
El mètode retorna un valor booleà (TRUE/FALSE) indicant si la connexió s'ha realitzat correctament. Realitzar desconnexió del servidor FTPPer realitzar la desconnexió del servidor FTP seguirem un patró com el mostrat en el següent exemple:
if (this.ftpClient != null ) { if (ftpClient.isConnected()) { ftpClient.disconnect(); } } Realitzarem doncs els següents passos:
Realitzar download d'un fitxerPer realitzar un download d'un fitxer seguirem un patró com el mostrat en el següent exemple:
if (this.ftpClient != null ) { ftpClient.login(userName, password, host); if (ftpClient.isConnected()) { InputStream stream = ftpClient.retrieveFileStream(serverFile); ftpClient.disconnect(); } } Realitzarem doncs els següents passos:
Es crida el mètode retrieveFileStream() que amb els següents paràmetres:
I retorna:
Realitzar upload d'un fitxerPer realitzar un upload d'un fitxer seguirem un patró com el mostrat en el següent exemple:
if (this.ftpClient != null ) { ftpClient.login(userName, password, host); if (ftpClient.isConnected()) { ftpClient.storeFile(serverFileUploaded, input); ftpClient.disconnect(); } } Realitzarem doncs els següents passos:
Es crida el mètode storeFile() que amb els següents paràmetres:
Obtenir la llista de noms dels fitxers del servidor remotPer obtenir la llista de fitxers en una carpeta d'un servidor remot seguirem un patró com el mostrat en el següent exemple:
if (this.ftpClient != null ) { ftpClient.login(userName, password, host); if (ftpClient.isConnected()) { String[] listFileNames = ftpClient.listNames(serverFolder) } } Realitzarem doncs els següents passos:
Es crida el mètode listNames() que amb els següents paràmetres:
El mètode retorna un array de Strings amb els noms dels fitxers de la carpeta del servidor remot. Executar una comanda FTPPer executar una comanda FTP seguirem un patró com el mostrat en el següent exemple:
if (this.ftpClient != null ) { ftpClient.login(userName, password, host); if (ftpClient.isConnected()) { String line = ftpClient.sendCommand(command); } } Realitzarem doncs els següents passos:
Es crida el mètode sendCommand() que amb els següents paràmetres:
El mètode retorna un String el resultat de l'execució de la comanda FTP en el servidor remot. ExemplesTests UnitarisUn exemple d'utilització del servei de FTP són els tests unitaris, a on s'obté el bean del servei a partir del fitxer de definició (applicationContext.xml) i s'envia un log amb les sortides especificades. S'ha de tenir en compte que s'ha de disposar d'accés a un servidor remot mitjançant el protocol FTP per poder realitzar els tests. package net.gencat.ctti.canigo.services.ftp.test; ... La utilització del servei es independent de la configuració del mateix. Així, un possible fitxer de configuració del servei seria:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- FTP service --> <bean id="ftpService" class="net.gencat.ctti.canigo.services.ftp.impl.FtpClient"> <property name="logService"> <ref bean="loggingService" /> </property> </bean> <!-- LOGGING service --> <bean id="loggingService" class="net.gencat.ctti.canigo.services.logging.log4j. Log4JServiceImpl" init-method="init"> <property name="configurator"> <ref local="loggingConfigurator"/> </property> </bean> <!-- configurator bean --> <bean id="loggingConfigurator" class="net.gencat.ctti.canigo.services.logging.log4j.xml. HostDOMConfigurator"> <property name="configFileName"> <value>classpath:log4j-test.xml</value> </property> </bean> </beans> ... public void testConnectAndLogin() throws Exception { FtpClientIF ftpClient = getFtpService(); assertTrue(ftpClient.login(userName, password, host)); if (ftpClient.isConnected()) { ftpClient.disconnect(); } if (getLogService() != null) { getLogService().getLog(this.getClass().getName()).debug("End testConnectAndLogin()"); } } public void testConnectFailed() throws Exception { password = "incorrectPasword"; FtpClientIF ftpClient = getFtpService(); assertFalse(ftpClient.login(userName, password, host)); if (ftpClient.isConnected()) { ftpClient.disconnect(); } if (getLogService() != null) { getLogService().getLog(this.getClass().getName()).debug("End testConnectFailed()"); } } public void testSendRawCommand() throws Exception { FtpClientIF ftpClient = getFtpService(); ftpClient.login(userName, password, host); int returnCodeOk = 257; int returnCode = ftpClient.sendCommand("PWD"); if (ftpClient.isConnected()) { ftpClient.disconnect(); } assertEquals(returnCodeOk, returnCode); if (getLogService() != null) { getLogService().getLog(this.getClass().getName()).debug("End testSendRawCommand()"); } } public void testListFileNames() throws Exception { FtpClientIF ftpClient = getFtpService(); ftpClient.login(userName, password, host); String[] listFileNames = ftpClient.listNames(serverFolder); if (ftpClient.isConnected()) { ftpClient.disconnect(); } assertTrue(0<listFileNames.length); if (getLogService() != null) { getLogService().getLog(this.getClass().getName()).debug("End testListFileNames()"); } } public void testUploadFile() throws Exception { FtpClientIF ftpClient = getFtpService(); ftpClient.login(userName, password, host); InputStream input; input = new FileInputStream(localFolder+localFile); String serverFileUploaded = localFile; ftpClient.storeFile(serverFileUploaded, input); input.close(); // validate file at server boolean existsAtServer = false; String[] listFileNames = ftpClient.listNames(serverFolder); if (listFileNames != null) { for (int i=0; i<listFileNames.length; i++) { String fileName = (String)listFileNames[i]; if (localFile.equals(fileName)) { existsAtServer = true; break; } } } if (ftpClient.isConnected()) { ftpClient.disconnect(); } assertTrue(existsAtServer); if (getLogService() != null) { getLogService().getLog(this.getClass().getName()).debug("End testUploadFile()"); } } public void testDownloadFile() throws Exception { FtpClientIF ftpClient = getFtpService(); ftpClient.login(userName, password, host); InputStream inputStream = ftpClient.retrieveFileStream(serverFile); byte[] buf = new byte[4096]; FileOutputStream fileDownload = new FileOutputStream(localFolder+serverFile); for (int len=-1;(len=inputStream.read(buf))!=-1;) { fileDownload.write(buf,0,len); } fileDownload.flush(); if (ftpClient.isConnected()) { ftpClient.disconnect(); } File file = new File(localFolder+serverFile); assertTrue(file.exists()); if (getLogService() != null) { getLogService().getLog(this.getClass().getName()).debug("End testDownloadFile()"); } } private FtpClientIF getFtpService() { BeanFactory beanFactory = new ClassPathXmlApplicationContext("applicationContext.xml"); FtpClientIF ftpClient = (FtpClientIF)beanFactory.getBean("ftpService"); logService = ftpClient.getLogService(); assertNotNull(ftpClient); return ftpClient; } ... |